from flask import Flask, render_template, request, redirect, url_for, session, jsonify
from flask_socketio import SocketIO, emit, join_room, leave_room
from flask_sqlalchemy import SQLAlchemy
from datetime import datetime
import os
from functools import wraps

app = Flask(__name__)
app.config['SECRET_KEY'] = os.urandom(24)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///chatroom.db'  # SQLite 数据库
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

# 初始化数据库和 SocketIO
db = SQLAlchemy(app)
socketio = SocketIO(app, cors_allowed_origins="*")  # 允许跨域（开发环境）

# 数据库模型
class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(50), unique=True, nullable=False)
    password = db.Column(db.String(100), nullable=False)
    created_at = db.Column(db.DateTime, default=datetime.utcnow)

class Message(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
    content = db.Column(db.String(500), nullable=False)  # 消息内容
    timestamp = db.Column(db.DateTime, default=datetime.utcnow)
    
    # 关联用户
    user = db.relationship('User', backref=db.backref('messages', lazy=True))

# 登录验证装饰器
def login_required(f):
    @wraps(f)
    def decorated_function(*args, **kwargs):
        if 'user_id' not in session:
            return redirect(url_for('login', next=request.url))
        return f(*args, **kwargs)
    return decorated_function

# 初始化数据库（首次运行时创建表）
with app.app_context():
    db.create_all()

# 路由
@app.route('/')
def login():
    return render_template('login.html')

@app.route('/register', methods=['GET', 'POST'])
def register():
    if request.method == 'POST':
        username = request.form['username']
        password = request.form['password']
        
        if not username or not password:
            return "用户名和密码不能为空"
        
        if User.query.filter_by(username=username).first():
            return "用户名已存在"
        
        new_user = User(username=username, password=password)
        db.session.add(new_user)
        db.session.commit()
        return redirect(url_for('login'))
    
    return render_template('register.html')

@app.route('/login', methods=['POST'])
def do_login():
    username = request.form['username']
    password = request.form['password']
    
    user = User.query.filter_by(username=username, password=password).first()
    if user:
        session['user_id'] = user.id
        session['username'] = user.username
        return redirect(url_for('chat'))
    else:
        return "用户名或密码错误"

@app.route('/chat')
@login_required
def chat():
    # 获取最近20条消息
    recent_messages = Message.query.order_by(Message.timestamp.desc()).limit(20).all()[::-1]
    return render_template('chat.html', 
                          username=session['username'],
                          recent_messages=recent_messages)

@app.route('/logout')
def logout():
    session.pop('user_id', None)
    session.pop('username', None)
    return redirect(url_for('login'))

# SocketIO 事件处理
@socketio.on('connect')
def handle_connect():
    if 'user_id' in session:
        # 用户连接时加入聊天室
        join_room('chatroom')
        username = session['username']
        emit('system_message', {
            'content': f'{username} 加入了聊天室',
            'timestamp': datetime.now().strftime('%H:%M:%S')
        }, room='chatroom')

@socketio.on('disconnect')
def handle_disconnect():
    if 'user_id' in session:
        # 用户断开连接时离开聊天室
        leave_room('chatroom')
        username = session['username']
        emit('system_message', {
            'content': f'{username} 离开了聊天室',
            'timestamp': datetime.now().strftime('%H:%M:%S')
        }, room='chatroom')

@socketio.on('send_message')
def handle_message(data):
    if 'user_id' not in session:
        return
    
    user_id = session['user_id']
    username = session['username']
    content = data['content'].strip()
    
    if content:
        # 保存消息到数据库
        new_message = Message(user_id=user_id, content=content)
        db.session.add(new_message)
        db.session.commit()
        
        # 广播消息给所有在线用户
        emit('new_message', {
            'username': username,
            'content': content,
            'timestamp': datetime.now().strftime('%H:%M:%S'),
            'message_id': new_message.id
        }, room='chatroom')

if __name__ == '__main__':
    # 用 socketio 启动应用（替代 app.run）
    socketio.run(app, debug=True, host='0.0.0.0', port=5000)